<template>
  <div>
    <!-- 头部导航 -->
    <!-- placeholder占位作用 -->
    <van-nav-bar fixed placeholder>
      <template #left>
        <img src="../../assets/toutiao_logo.png" alt="" class="logo" />
      </template>
      <template #right>
        <!-- 行内样式的尺寸大小需要手动转换为rem -->
        <van-icon
          name="search"
          size="0.48rem"
          @click="$router.push('/search')"
        />
      </template>
    </van-nav-bar>
    <!-- 标签栏 -->
    <!-- v-model绑定标签的name属性，来控制当前激活的标签 -->
    <van-tabs
      v-model="active"
      animated
      sticky
      offset-top="1.22666667rem"
      @change="tabsChangeFn"
      :before-change="beforeChangeFn"
    >
      <!-- name值为频道的id，可以绑定tabs上的v-model -->
      <van-tab
        :name="obj.id"
        :title="obj.name"
        v-for="obj in userChannelList"
        :key="obj.id"
      >
        <!-- 文章列表组件 -->
        <!-- 将频道id传给子组件 -->
        <ArticleList :channleId="active"></ArticleList>
      </van-tab>
    </van-tabs>
    <!-- 编辑的+号 -->
    <van-icon
      @click="plusFn"
      name="plus"
      size="0.37333334rem"
      class="moreChannels"
    />

    <!-- 反馈面板 -->
    <!-- v-modle绑定是否显示反馈面板 -->
    <!-- actions绑定反馈面板显示的内容 -->
    <!-- get-container 设置挂载点 -->
    <!-- close 反馈面板关闭事件 -->
    <van-action-sheet
      v-model="$store.state.ActionsShow"
      :actions="actionArr"
      :cancel-text="cancleText"
      @select="onSelect"
      @cancel="cancelFn"
      get-container="body"
    />
    <!-- 弹出层组件 -->
    <van-popup v-model="show" class="channel_van-popup_wrap">
      <!-- 子组件点击事件触发了本组件的自定义事件 -->
      <!-- 将用户已选频道列表传递给子组件 -->
      <ChannelEdit
        @colseEvent="closeFn"
        :checkedChannelList="userChannelList"
        @addEvent="addChannelFn"
        @deleteChannelEvent="deleteChannelFn"
        v-model="active"
      ></ChannelEdit>
    </van-popup>
  </div>
</template>

<script>
// 1.首页结构的铺设
// 使用头部导航van-NavBar组件
// 头部导航左右两侧使用插槽技术
// 定制头部导航字体颜色@nav-bar-icon-color
// 2.标签页的铺设
// 使用van-tabs标签页组件，并添加动画属性animated
// 3.频道数据的铺设
// 在api中定义获取频道的接口方法
// 在home中初始化后调用请求方法，获取请求结果
// 将请求结果赋值给内部变量，在标签van-tab上使用v-for循环铺设页面
// 4. 文章内容列表组件封装
// Home/index.vue ==> ArticleList.vue ==> ArticleItem.vue
// 在ArticleList.vue里面循环使用(van-tab循环多次，就创建了多个在ArticleList)
// 5. tab标签导航使用粘性布局
// 网页有竖向滚动条时，tab标签栏一直在
// 开启van-tab的粘性定位属性
// css单位小数保留6-8位
// 6. 获取文章内容列表
// 封装接口方法，在ArticleList里面调用方法，获取请求结果，并将其赋值给内部
// v-for循环
// 7. 点击tab栏切换，显示相应的内容(父传子)
// van-tab设置name属性=值（频道id),将id传递给ArticleItem里面
// 在ArticleItem 接收id值，初始化后发起请求文章内容列表，
/* ************************** */
// 19. 顶部+号功能
// 字体图标的使用(找到字体图标文件，main.js中引入css文件，在使用的时候直接添加类名即可)
// home/index.vue中的tabs标签页向左让出距离，使用van-icon组件，添加字体图标，直接复制代码，调节样式
// 引入使用popup(基础用法)
// 点击+号，绑定事件，弹出弹出层
// 弹出层内容设置，单独封装一个文件channelEdit.vue,在home/index中引入注册使用
// 全局注册相关组件
// 20.弹出层的关闭功能
// 子组件中点击x,关闭弹出层
// 子组件点击事件中触发父组件的自定义事件，父组件中绑定自定义事件，时间函数中关闭弹出层
// 21. 弹出层布局
// 我的频道内容铺设：父组件中传递用户已选频道列表给子组件，子组件中循环van-clo生成频道列表
// 更多频道铺设：封装接口,更多频道 = 所有频道列表 - 用户已选频道
// 在ChanneList里面creaded里面调用接口发送请求，
// 在computed里面定义更多频道的变量unCheckChannelList，
// 使用filter循环所有频道列表，在filter中使用findIndexcha查找id是否相同，进行去重操作
// 使用v-for循环van-clo铺设更多频道页面结构
// 22. 弹出层的编辑操作
// ChanneList里面绑定点击事件，
// data里面设置变量控制x号的显示,使用v-show绑定，并且id不为0(推荐没有x号)
// 使用变量更改文字显示(三元表达式) 进去/删除   完成/编辑
//* ************************ */
// 23. 新增频道
// 在子组件中频道名上绑定点击事件，触发父组件的自定义事件，并传入当前的频道对象
// 在父组件内自定义事件内将传过来的频道对象添加到用户已选频道列表中
// 添加判断:当显示编辑时，进行添加操作
// 24. 更新频道操作()
// api中封装更新频道的接口方法（参数为频道对象，频道id和索引值），
// 在添加频道后，遍历用户已选频道，将频道数组里的频道对象浅拷贝给新的对象，将index赋值给新对象的seq属性，删除其name属性
// 将新对象组成新的数组作为参数，发送更新频道的请求，进行频道更新
// 25. 删除频道******
// 子组件中点击x，触发父组件的自定义事件，并传递相应频道id
// 父组件自定义事件中，调用接口删除后台数据
// 然后在用户已选频道中找到相应索引，删除相应数组元素
// 26. 小功能实现
// *点击弹出层的关闭按钮,关闭弹出层
// *点击频道名称(阻止删除按钮的冒泡)，进入频道，关闭整个弹窗
//  触发父组件的input事件，并传递频道id,父组件内给子组件身上绑定v-modle(v-modle与tabs的name值已绑定)
import {
  getUserChannelListApi,
  dislikesArticleApi,
  reportArticleApi,
  setUserChannelListApi,
  removeChannelListApi
} from '@/api'
import ArticleList from './ArticleList.vue'
import ChannelEdit from './ChannelEdit.vue'
import { mapState, mapMutations } from 'vuex'
// 组件缓存只是缓存了标签，里面的变量值不会被缓存
export default {
  data () {
    return {
      userChannelList: [], // 用户已选频道列表
      active: 0,
      actionArr: [], // 反馈面板的显示内容
      cancleText: '取消', // 取消文字，默认为取消
      show: false, // 弹出层的显示
      nameToTop: {} // 用来保存频道索引和切换频道时频道页面的滚动距离
    }
  },
  // 初始化完成，获取用户已选频道，并将频道列表赋值给内部变量
  async created () {
    const re = await getUserChannelListApi()
    // console.log(re)
    this.userChannelList = re.data.data.channels
    // 默认显示一级反馈面板内容
    this.actionArr = this.firstActions
    // 初始化完成检测window的滚动事件，将滚动距离保存到路由元信息上
    // console.log(this.$route)
    window.addEventListener('scroll', () => {
      this.$route.meta.scrollT = document.documentElement.scrollTop
    })
  },
  // 组件激活时设置html滚动距离
  activated () {
    // console.log(this.$route)
    document.documentElement.scrollTop = this.$route.meta.scrollT
  },
  computed: {
    ...mapState(['firstActions', 'secondActions', 'actionArtId'])
  },
  methods: {
    ...mapMutations(['ActionsShowMutation']),
    // 点击反馈面板选项时触发
    async onSelect (item) {
      // 判断如果点击的反馈垃圾内容，则显示二级面板(即切换面板内容)
      // console.log(item)
      if (item.name === '反馈垃圾内容') {
        this.actionArr = this.secondActions
        // 取消文字改为返回
        this.cancleText = '返回'
        // 如果点击的是不感兴趣，获取文章id调用接口发送请求,
      } else if (item.name === '不感兴趣') {
        const res = await dislikesArticleApi(this.actionArtId)
        console.log(res)
        // 关闭反馈面板
        this.ActionsShowMutation(false)
      } else {
        // 举报文章
        const res = await reportArticleApi({
          target: this.actionArtId,
          type: item.value
        })
        console.log(res)
        this.ActionsShowMutation(false)
        this.actionArr = this.firstActions
        this.$toast.success('举报成功')
      }
    },
    // 点击取消按钮
    cancelFn () {
      // 如果取消文字为返回，则返回一级反馈面板，更改取消文字
      if (this.cancleText === '返回') {
        // 显示面板
        this.ActionsShowMutation(true)
        this.actionArr = this.firstActions
        this.cancleText = '取消'
      }
    },
    // 点击+号，弹出层显示
    plusFn () {
      this.show = true
    },
    // 关闭弹出层
    closeFn (bool) {
      this.show = bool
    },
    // 添加频道
    async addChannelFn (item) {
      // console.log(item)
      // 将新选频道添加到用户已选频道中
      this.userChannelList.push(item)
      // 调用接口，更新数据
      // 处理用户已选频道数组里的频道对象
      const newArr = []
      this.userChannelList.forEach((obj, index) => {
        if (obj.id !== 0) {
          // 扩展运算(将原对象里的值拿出来，新城一个新的对象)
          // 浅拷贝(将obj里的key和value浅拷贝到新对象里，对原对象没有影响)
          const newObj = { ...obj }
          newObj.seq = index
          delete newObj.name
          newArr.push(newObj)
        }
      })
      const res = await setUserChannelListApi(newArr)
      console.log(res)
    },
    // 删除频道,删除页面和后台频道
    async deleteChannelFn (channelId) {
      console.log(channelId)
      const index = this.userChannelList.findIndex(obj => obj.id === channelId)
      this.userChannelList.splice(index, 1)
      const res = await removeChannelListApi(channelId)
      console.log(res)
    },
    // tabs切换时，将上次保存的滚动位置赋值给html
    // 如果从下面切换到里一个频道，滚动条会上来，滚动位置为0
    tabsChangeFn () {
      setTimeout(() => {
        document.documentElement.scrollTop = this.nameToTop[this.active]
      }, 0)
    },
    // tabs切换前，将本频道html的滚动距离保存到对象中
    beforeChangeFn () {
      this.nameToTop[this.active] = document.documentElement.scrollTop
      return true
    }
  },
  // 失去激活时（组件被切走）
  deactivated () {
    // 页面离开时，关闭反馈面板
    this.ActionsShowMutation(false)
  },
  components: {
    ArticleList,
    ChannelEdit
  }
}
</script>

<style lang="less" scoped>
.logo {
  height: 30px;
  width: 100px;
}
// 设置 tabs 容器的样式
/deep/ .van-tabs__wrap {
  padding-right: 30px;
  background-color: #fff;
}

// 设置小图标的样式
.moreChannels {
  position: fixed;
  top: 62px;
  right: 8px;
  z-index: 999;
}
/* 频道编辑弹出层铺满屏幕 */
.edit_wrap {
  width: 100%;
  height: 100%;
}
/* 设置弹出层宽高100%，颜色透明 */
.channel_van-popup_wrap {
  background-color: transparent;
  height: 100%;
  width: 100%;
  background-color: white;
}
</style>
